#ifndef _TAROT_CARD_H
#define _TAROT_CARD_H

#include <stdio.h>
#include "../Main.h"
#include "../occult/Occult.h"
#include "Tarot.h"


enum {
	CARD_BACK					= 0x0001,
	CARD_REVERSED				= 0x0002,
	CARD_HIDE_REVERSED		= 0x0004,
	CARD_FLIPPED				= 0x0008,
	CARD_MOBILE					= 0x0010,
	CARD_PICKED					= 0x0020,
	CARD_SELECTED				= 0x0040,
};


class TarotDeck;
class CardSet;


class Card {
private:
	TarotDeck *deck;				/**< TarotDeck the card belongs to. */
	CardSet *set;					/**< CardSet the card is in. */
	char *name;						/**< Name of card. */
	char *title;					/**< Title of card. */
	int value;						/**< Card value, index in the deck. */
	unsigned long state;			/**< Card state, flags for the different states the card is in. */
	int x;							/**< X position. */
	int y;							/**< Y position. */
	int width;						/**< Width of card. */
	int height;						/**< Height of card. */
	struct {
		CardSet *set;				/**< The original CardSet of the card after the deck is spread. */
		int state;					/**< The original state of the card after the deck is spread. */
		int x;						/**< The original X position of the card after the deck is spread. */
		int y;						/**< The original Y position of the card after the deck is spread. */
		int width;					/**< The original width of the card after the deck is spread. */
		int height;					/**< The original height of the card after the deck is spread. */
	} origin;
	int number;						/**< Card number, for major arcana 0-21, for minor arcana 1-14. */
	tarot_element element;		/**< Card element. */
	int sg1;							/**< Primary astrological Symbol. */
	int sg2;							/**< Secondary astrological Symbol. */
	tarot_arcana arcana;			/**< Arcana card belongs to. */
	char eds[4];					/**< Elemental Dignities values. */
	cairo_surface_t *image;		/**< Card front image. */

	void flip();

public:
	Card(TarotDeck &d,int v,int s=1);
	~Card();

	void setCardSet(CardSet &cs) { set = &cs; }
	CardSet &getCardSet() { return *set; }

	void setName(const char *n);
	char *getName() { return name; }
	void setTitle(const char *t);
	char *getTitle() { return title; }

	void setValue(int v);
	int getValue() { return value; }
	int getNumber() { return number; }
	tarot_element getElement() { return element; }
	int primarySymbol() { return sg1; }
	int secondarySymbol() { return sg2; }
	tarot_arcana getArcana() { return arcana; }
	bool isMajor() { return arcana==TAROT_MAJOR; }
	bool isCourt() { return arcana==TAROT_COURT; }
	bool isMinor() { return arcana==TAROT_MINOR; }

	void setImage(cairo_surface_t *i);
	cairo_surface_t *getImage();

	void setState(int s) { setFlipped(s&CARD_FLIPPED);state = s; }
	void setState(int s,bool set) { if(s&CARD_FLIPPED) setFlipped(set);state = set? state|s : state&~s; }
	bool isFront() { return !(state&CARD_BACK); }
	void setFront() { state &= ~CARD_BACK; }
	bool isBack() { return state&CARD_BACK; }
	void setBack() { state |= CARD_BACK; }
	bool isReversed() { return state&CARD_REVERSED; }
	void setReversed(bool r) { state = r? state|CARD_REVERSED : state&~CARD_REVERSED; }
	bool isHideReversed() { return state&CARD_HIDE_REVERSED; }
	void setHideReversed(bool f) { state = f? state|CARD_HIDE_REVERSED : state&~CARD_HIDE_REVERSED; }
	bool isFlipped() { return state&CARD_FLIPPED; }
	void setFlipped(bool f);
	bool isMobile() { return state&CARD_MOBILE; }
	void setMobile(bool g) { state = g? state|CARD_MOBILE : state&~CARD_MOBILE; }
	bool isPicked() { return state&CARD_PICKED; }
	void setPicked(bool p) { state = p? state|CARD_PICKED : state&~CARD_PICKED; }
	bool isSelected() { return state&CARD_SELECTED; }
	void setSelected(bool s) { state = s? state|CARD_SELECTED : state&~CARD_SELECTED; }

	void getRectangle(GdkRectangle &r) { r.x = x,r.y = y,r.width = width,r.height = height; }
	void getBounds(GdkRectangle &r) { r.x = x-5,r.y = y-5,r.width = width+10,r.height = height+10; }
	void setLocation(Card &c) { x = c.x,y = c.y; }
	void setLocation(int x,int y) { this->x = x,this->y = y; }
	int getX() { return x; }
	int getY() { return y; }
	void setSize(int w,int h) { this->width = w,this->height = h; }
	int getWidth() { return width; }
	int getHeight() { return height; }
	bool contains(int x2,int y2) { return x2>=x && y2>=y && x2<x+width && y2<y+height; }
	bool intersects(GdkRectangle &r) { return r.x<x+width && r.y<y+height && r.x+r.width>=x && r.y+r.height>=y; }
	bool intersects(Card &c) { return c.x<x+width && c.y<y+height && c.x+c.width>=x && c.y+c.height>=y; }

	void makeOriginalState();
	void returnToOriginalState();

	int ed(int e) { return eds[e]; }
};



#endif /* _TAROT_CARD_H */


